home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved. The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
- */
-
- #ifndef lint
- char copyright[] =
- "@(#) Copyright (c) 1980 Regents of the University of California.\n\
- All rights reserved.\n";
- #endif not lint
-
- /*
- * mv file1 file2
- */
- #include <sys/param.h>
- #include <sys/stat.h>
- #include <sys/time.h>
-
- #include <stdio.h>
- #include <sys/dir.h>
- #include <errno.h>
- #include <signal.h>
- #include "tmp/libpq-fs.h"
-
- #define DELIM '/'
- #define MODEBITS 07777
-
- #define ISDIR(st) (((st).st_mode&S_IFMT) == S_IFDIR)
- #define ISLNK(st) (((st).st_mode&S_IFMT) == S_IFLNK)
- #define ISREG(st) (((st).st_mode&S_IFMT) == S_IFREG)
- #define ISDEV(st) \
- (((st).st_mode&S_IFMT) == S_IFCHR || \
- ((st).st_mode&S_IFMT) == S_IFBLK || \
- ((st).st_mode&S_IFMT) == S_IFIFO)
-
- char *sprintf();
- char *dname();
- struct pgstat s1, s2;
- int iflag = 0; /* interactive mode */
- int fflag = 0; /* force overwriting */
- extern int p_errno;
- extern char *getenv();
-
- main(argc, argv)
- register char *argv[];
- {
- register i, r;
- register char *arg;
- char *dest;
- char *dbname;
-
- if (argc < 2)
- goto usage;
-
- if ((dbname = getenv("DATABASE")) == (char *) NULL) {
- fprintf(stderr, "no database specified in env var DATABASE\n");
- fflush(stderr);
- exit (1);
- }
-
- PQsetdb(dbname);
-
- while (argc > 1 && *argv[1] == '-') {
- argc--;
- arg = *++argv;
-
- /*
- * all files following a null option
- * are considered file names
- */
- if (*(arg+1) == '\0')
- break;
- while (*++arg != '\0') switch (*arg) {
-
- case 'i':
- iflag++;
- break;
-
- case 'f':
- fflag++;
- break;
-
- default:
- goto usage;
- }
- }
- if (argc < 3)
- goto usage;
- dest = argv[argc-1];
- if (p_stat(dest, &s2) >= 0 && ISDIR(s2)) {
- r = 0;
- for (i = 1; i < argc-1; i++)
- r |= movewithshortname(argv[i], dest);
- exit(r);
- }
- if (argc > 3)
- goto usage;
- r = move(argv[1], argv[2]);
- PQfinish();
- exit(r);
- /*NOTREACHED*/
- usage:
- fprintf(stderr,
- "usage: mv [-if] f1 f2 or mv [-if] f1 ... fn d1 (`fn' is a file or directory)\n");
- return (1);
- }
-
- movewithshortname(src, dest)
- char *src, *dest;
- {
- register char *shortname;
- char target[MAXPATHLEN + 1];
-
- shortname = dname(src);
- if (strlen(dest) + strlen(shortname) > MAXPATHLEN - 1) {
- error("%s/%s: pathname too long", dest,
- shortname);
- return (1);
- }
- sprintf(target, "%s/%s", dest, shortname);
- return (move(src, target));
- }
-
- move(source, target)
- char *source, *target;
- {
- int targetexists;
-
- if (p_stat(source, &s1) < 0) {
- Perror2(source, "Cannot access");
- return (1);
- }
- /*
- * First, try to rename source to destination.
- * The only reason we continue on failure is if
- * the move is on a nondirectory and not across
- * file systems.
- */
- targetexists = p_stat(target, &s2) >= 0;
- if (targetexists) {
- if (s1.st_ino == s2.st_ino) {
- error("%s and %s are identical", source, target);
- return (1);
- }
- if (iflag && !fflag && isatty(fileno(stdin)) &&
- query("remove %s? ", target) == 0)
- return (1);
- #if 0
- if (access(target, 2) < 0 && !fflag && isatty(fileno(stdin))) {
- if (query("override protection %o for %s? ",
- s2.st_mode & MODEBITS, target) == 0)
- return (1);
- }
- #endif
- }
- if (p_rename(source, target) >= 0)
- return (0);
- Perror2(p_errno == PENOENT && targetexists == 0 ? target : source,
- "rename");
- return (1);
-
- #if 0
- if (targetexists && p_unlink(target) < 0) {
- Perror2(target, "Cannot unlink");
- return (1);
- }
- if (ISREG(s1)) {
- register int fi, fo, n;
- struct timeval tv[2];
- char buf[MAXBSIZE];
-
- fi = p_open(source, 0);
- if (fi < 0) {
- Perror(source);
- return (1);
- }
-
- fo = p_creat(target, s1.st_mode & MODEBITS,Unix);
- if (fo < 0) {
- Perror(target);
- p_close(fi);
- return (1);
- }
-
- for (;;) {
- n = p_read(fi, buf, sizeof buf);
- if (n == 0) {
- break;
- } else if (n < 0) {
- Perror2(source, "p_read");
- p_close(fi);
- p_close(fo);
- return (1);
- } else if (p_write(fo, buf, n) != n) {
- Perror2(target, "p_write");
- p_close(fi);
- p_close(fo);
- return (1);
- }
- }
-
- p_close(fi);
- if (p_close(fo) < 0) {
- Perror2(target, "p_write");
- return (1);
- }
- #if 0
- tv[0].tv_sec = s1.st_atime;
- tv[0].tv_usec = 0;
- tv[1].tv_sec = s1.st_mtime;
- tv[1].tv_usec = 0;
- (void) utimes(target, tv);
- #endif
- goto cleanup;
- }
- error("%s: unknown file type %o", source, s1.st_mode);
- return (1);
-
- cleanup:
- if (p_unlink(source) < 0) {
- /*
- * If the unlink failed because of ENOENT we will assume
- * that somebody rm'ed the file before we got a chance
- * to do it. So just report the failure but leave the
- * target there. Also, don't remove target when target
- * existed previously.
- */
- if (p_errno == PENOENT || targetexists)
- Perror2(source, "Cannot unlink");
- else {
- (void) p_unlink(target);
- Perror2(source, "Cannot unlink");
- }
- return (1);
- }
- return (0);
- #endif
- }
-
- /*VARARGS*/
- query(prompt, a1, a2)
- char *a1;
- {
- register int i, c;
-
- fprintf(stderr, prompt, a1, a2);
- i = c = getchar();
- while (c != '\n' && c != EOF)
- c = getchar();
- return (i == 'y');
- }
-
- char *
- dname(name)
- register char *name;
- {
- register char *p;
-
- p = name;
- while (*p)
- if (*p++ == DELIM && *p)
- name = p;
- return name;
- }
-
- /*VARARGS*/
- error(fmt, a1, a2)
- char *fmt;
- {
-
- fprintf(stderr, "mv: ");
- fprintf(stderr, fmt, a1, a2);
- fprintf(stderr, "\n");
- }
-
- Perror(s)
- char *s;
- {
- char buf[MAXPATHLEN + 10];
-
- sprintf(buf, "mv: %s", s);
- perror(buf);
- }
-
- Perror2(s1, s2)
- char *s1, *s2;
- {
- char buf[MAXPATHLEN + 20];
-
- sprintf(buf, "mv: %s: %s", s1, s2);
- perror(buf);
- }
-